`timescale 1ns/1ns


module net_top(
    
    input 			sysclk_i,						// 输入时钟  25MHz
    input 			reset_i,						// 复位输入（常高）

    // RGMII 接口
    output [3:0]  	rgmii_txd,
    output        	rgmii_tx_ctl,
    output        	rgmii_txc,
    input  [3:0]  	rgmii_rxd,
    input         	rgmii_rx_ctl,
    input         	rgmii_rxc,
    // MDIO 接口
    //---------------
    inout         	mdio,
    output        	mdc,
                                        
    output [6:0] 	led_o,				// 输出led灯                

	input			uart_rx_i,			// 串口输入
    output			uart_tx_o			// 串口输出
    
 );

    wire 	clk_125mhz;		
    wire 	clk_50mhz;		

    // 将25MHz频率更改为 MDC 频率（周期为 80ns）
    pll_clock(
        .refclk(sysclk_i),
        .reset(0),
        .clk0_out(clk_125mhz),
        .clk1_out(clk_50mhz)
    );
    


    // 发送器用户侧端口
    wire                tx_clk_en;          // 发送器时钟使能信号。
    reg         [7:0]   tx_data;            // 要发送的帧数据
    reg                 tx_data_en;         // 发送帧数据的控制使能信号
    wire                tx_rdy;             // 握手信号，MAC核准备好接收当前帧时，输出高电平。
    reg                 tx_stop;            // 输入高电平时，强制 MAC 核终止当前帧发送。
    reg         [7:0]   tx_ifg_val;         // 可配置的帧间间隙调整值。
    wire                tx_collision;       // 仅在半双工模式下该信号有效。由 MAC 核声明介质发生冲突，正在进行的任何传输均应中止。
    wire                tx_retransmit;      // 仅在半双工模式下该信号有效。当与 tx_collision 信号同时为高电平时，提示用户应该重新提供已终止的帧数据给MAC 核以进行重传。
    wire        [28:0]  tx_status_vector;   // 发送前一帧的状态统计信息。
    wire                tx_status_vld;      // 在帧发送结束时为高电平


    // 接收器用户侧端口
    reg                 rx_clk_en;          // 接收器时钟使能信号。
    wire        [7:0]   rx_data;            // 接收的帧数据
    wire                rx_data_vld;        // 接收帧数据的有效控制信号。
    wire                rx_correct_frame;   // 在帧数据接收结束时输出一个周期高电平，指示该帧接收正确
    wire                rx_error_frame;     // 在帧数据接收结束时输出一个周期高电平，指示该帧接收错误。
    wire        [26:0]  rx_status_vector;   // 接收前一帧的状态统计信息。
    wire                rx_status_vld;      // 在帧接收结束时为高电平，指示 rx_status_vector 有效。


    // 复位、时钟、速度指示端口
    reg                 reset;              // 整个 MAC 核的异步复位，高电平有效
    reg                 tx_mac_clk;         // MAC 核的全局发送时钟。
    reg                 rx_mac_clk;         // MAC 核的全局接收时钟。
    wire                speed_10;           // 指示 MAC 核正在以 10 Mb / s 的速度运行。
    wire                speed_100;          // 指示 MAC 核正在以 100 Mb / s 的速度运行。
    wire                speed_1000;         // 指示 MAC 核正在以 1000 Mb / s 的速度运行。


    // 流控、单播地址端口
    reg                 pause_req;          // 发送暂停控制帧请求信号。MAC 核在下一帧插入暂停帧。
    reg         [15:0]  pause_val;          // 暂停值，插入发送暂停帧的参数字段中
    reg         [47:0]  pause_source_addr;	// 暂停帧 MAC 源地址。可以通过 AXI 管理配置接口写入该地址寄存器来覆盖它。
    reg         [47:0]  unicast_addr;       // 设置 MAC 的默认地址。可以通过 AXI 管理配置接口写入单播地址寄存器来覆盖它。



    // 管理配置端口
    wire                s_axi_aclk;         // AXI4-Lite 总线时钟。不小于 10Mhz。
    wire        [7:0]   s_axi_awaddr;       // 写地址
    wire                s_axi_awvalid;      // 写地址有效
    wire                s_axi_awready;      // 写地址就绪
    wire         [31:0] s_axi_wdata;        // 写数据
    wire                s_axi_wvalid;       // 写数据有效
    wire                s_axi_wready;       // 写数据就绪
    wire        [1:0]   s_axi_bresp;        // 写响应
    wire                s_axi_bvalid;       // 写响应有效
    wire                s_axi_bready;       // 写响应准备就绪
    wire         [7:0]  s_axi_araddr;       // 读地址
    wire                s_axi_arvalid;      // 读地址有效
    wire                s_axi_arready;      // 读地址就绪
    wire        [31:0]  s_axi_rdata;        // 读取数据
    wire        [1:0]   s_axi_rresp;        // 读响应
    wire                s_axi_rvalid;       // 读取数据有效
    wire                s_axi_rready;       // 读取数据准备就绪


    wire                init_axi_tx;
    wire                axi_tx_done;
    
    // 例化 axi 总线配置模块
    axi_master_cfg axi_master_cfg_blk(
        .init_axi_tx_i(init_axi_tx),                // 发起AXI事务
        .axi_tx_done_o(axi_tx_done),                // AXI事务完成时断言

        // AXI 总线
        .m_axi_aclk_i(clk_50mhz),                   // 输入的时钟信号 50mhz
        .m_axi_a_reset_i(~reset_i),                 // 异步复位信号
        .m_axi_awaddr_o(s_axi_awaddr),              // 写地址
        .m_axi_awvalid_o(s_axi_awvalid),            // 
        .m_axi_awready_i(s_axi_awready),            //
        .m_axi_wdata_o(s_axi_wdata),                // axi 写出数据内容
        .m_axi_wvalid_o(s_axi_wvalid),              // 
        .m_axi_wready_i(s_axi_wready),
        .m_axi_bresp_i(s_axi_bresp),
        .m_axi_bvalid_i(s_axi_bvalid),
        .m_axi_bready_o(s_axi_bready),
        .m_axi_araddr_o(s_axi_araddr),
        .m_axi_arvalid_o(s_axi_arvalid),
        .m_axi_arready_i(s_axi_arready),
        .m_axi_rdata_i(s_axi_rdata),
        .m_axi_rresp_i(s_axi_rresp),
        .m_axi_rvalid_i(s_axi_rvalid),
        .m_axi_rready_o(s_axi_rready),
           
    	.led_o(led_o),								// 输出led灯
        .uart_rx_i(uart_rx_i),
        .uart_tx_o(uart_tx_o)
    );


    // 向量配置端口
    reg         [19:0]  mac_cfg_vector;     // 当不使用 AXI4-Lite 管理接口时，向量配置总线执行 MAC 核基本功能的配置。详见 3.3 节表格。


    // GMII/MII 端口
    reg                 gmii_tx_clken;      // 发送器 GMII / MII 逻辑的时钟使能信号。结合 tx_mac_clk 信号支持三速（10/100/1000 Mbps）
                                            // 以太网 MAC 对应速度时钟。详见第 5 章节。
    wire        [3:0]   gmii_txd;           // MAC 发送的数据。当 MAC 核以 1Gb/s 速度运行时，此总线 8 位数据位宽有效。
                                            // 当 MAC 核以 10/100 Mb/s 速度运行时，此总线低 4位数据位宽有效。

    wire                gmii_tx_en;         // MAC 发送数据的使能控制信号。
    wire                gmii_tx_er;         // MAC 发送数据的错误标志信号。
    wire        [3:0]   gmii_rxd;           // MAC 接收的数据。当 MAC 核以 1Gb / s 速度运行时，此总线 8 位数据位宽有效。
                                            // 当 MAC 核以 10/100 Mb/s 速度运行时，此总线低 4位数据位宽有效。
    reg                 gmii_rx_vld;        // MAC 接收数据的有效控制信号。
    reg                 gmii_rx_er;         // MAC 接收数据的错误标志信号。
    reg                 gmii_crs;           // 输入到 MAC 核的载波侦听控制信号。
    reg                 gmii_col;           // 输入到 MAC 核的冲突控制信号。


    // MDIO 端口
    wire                mdio_clk;           // MDIO 时钟。由 AXI 管理接口配置产生，最大不能超过 2.5Mhz。
    reg                 mdio_in;            // 输入数据信号，用于对 PHY 配置和状态通信
    wire                mdio_out;           // 输出数据信号，用于对 PHY 配置和状态通信
    wire                mdio_oen;           // MDIO 信号的三态控制信号
                                            // “0”表示值 mdio_out 声明到 MDIO 总线上
                                            // “1”表示值 mdio_in 声明到 MDIO 总线上

	// mdio
    assign mdio = mdio_oen ? 1'bz : mdio_out;
    assign mdc = mdio_clk;
    always @(mdio)
    begin
        mdio_in = mdio;
    end
    

    // 实例化 TMAC 模块
    net_ip net_ip_blk
    (
        .gmii_col(gmii_col),
        .gmii_crs(gmii_crs),
        .gmii_rx_er(gmii_rx_er),
        .gmii_rx_vld(gmii_rx_vld),
        .gmii_rxd(gmii_rxd),
        .gmii_tx_clken(gmii_tx_clken),
        .mac_cfg_vector(mac_cfg_vector),
        .mdio_in(mdio_in),
        .pause_req(pause_req),
        .pause_source_addr(pause_source_addr),
        .pause_val(pause_val),
        .reset(reset),
        .rx_clk_en(rx_clk_en),
        .rx_mac_clk(rx_mac_clk),
        .s_axi_aclk(s_axi_aclk),
        .s_axi_araddr(s_axi_araddr),
        .s_axi_arvalid(s_axi_arvalid),
        .s_axi_awaddr(s_axi_awaddr),
        .s_axi_awvalid(s_axi_awvalid),
        .s_axi_bready(s_axi_bready),
        .s_axi_rready(s_axi_rready),
        .s_axi_wdata(s_axi_wdata),
        .s_axi_wvalid(s_axi_wvalid),
        .tx_clk_en(tx_clk_en),
        .tx_data(tx_data),
        .tx_data_en(tx_data_en),
        .tx_ifg_val(tx_ifg_val),
        .tx_mac_clk(tx_mac_clk),
        .tx_stop(tx_stop),
        .unicast_addr(unicast_addr),
        .gmii_tx_en(gmii_tx_en),
        .gmii_tx_er(gmii_tx_er),
        .gmii_txd(gmii_txd),
        .mdio_clk(mdio_clk),
        .mdio_oen(mdio_oen),
        .mdio_out(mdio_out),
        .rx_correct_frame(rx_correct_frame),
        .rx_data(rx_data),
        .rx_data_vld(rx_data_vld),
        .rx_error_frame(rx_error_frame),
        .rx_status_vector(rx_status_vector),
        .rx_status_vld(rx_status_vld),
        .s_axi_arready(s_axi_arready),
        .s_axi_awready(s_axi_awready),
        .s_axi_bresp(s_axi_bresp),
        .s_axi_bvalid(s_axi_bvalid),
        .s_axi_rdata(s_axi_rdata),
        .s_axi_rresp(s_axi_rresp),
        .s_axi_rvalid(s_axi_rvalid),
        .s_axi_wready(s_axi_wready),
        .speed_10(speed_10),
        .speed_100(speed_100),
        .speed_1000(speed_1000),
        .tx_collision(tx_collision),
        .tx_rdy(tx_rdy),
        .tx_retransmit(tx_retransmit),
        .tx_status_vector(tx_status_vector),
        .tx_status_vld(tx_status_vld)
    );

endmodule
